package com.apache.member.common;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import com.apache.tools.DateUtils;

/**
 * 扩展了DateUtils工具类,新增获取周内日期等操作
 * @author wanfuping  
 * @version V1.0
 */
public class DateUtil extends DateUtils {
	//用来全局控制 上一周，本周，下一周的周数变化    
	private static int weeks = 0;

	/**
	 * 获取当前日期时间，格式yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getNowTime() {
		return format(new Date(), DateUtils.FmtStr.yyyyMMdd_HHmmss.toString());
	}

	/**
	 * 获取当前日期时间，格式yyyy-MM-dd HH:mm:ss sss
	 * @return
	 */
	public static String getTodayTime() {
		return format(new Date(), DateUtils.FmtStr.yyyyMMdd_HHmmssSSS.toString());
	}

	/**
	 * 获取当前日期时间，格式yyyy-MM-dd
	 * @return
	 */
	public static String getNowTimeWithOutMinutes() {
		return format(new Date(), DateUtils.FmtStr.yyyyMMdd.toString());
	}

	/**
	 * 拼装日期 格式：yyyy-MM-dd 
	 * @param year 年份
	 * @param month 月份
	 * @param day 日
	 * @return
	 */
	private static String getDateStr(int year, int month, int day) {
		String monthStr = String.valueOf(month);
		String dayStr = String.valueOf(day);
		if (month < 10) {
			monthStr = "0" + month;
		}
		if (day < 10) {
			dayStr = "0" + day;
		}
		return year + "-" + monthStr + "-" + dayStr;
	}

	/**
	 * 获取指定日期的前一天日期
	 * @param date
	 * @return
	 */
	public static String getLastDate(Date date) {
		Calendar cd = Calendar.getInstance();
		cd.setTime(date);
		cd.add(GregorianCalendar.DATE, -1);
		return dateToStr(cd.getTime());
	}

	/**
	 * 获取指定日期的后一天日期
	 * @param date
	 * @return
	 */
	public static String getNextDate(Date date) {
		Calendar cd = Calendar.getInstance();
		cd.setTime(date);
		cd.add(GregorianCalendar.DATE, 1);
		return dateToStr(cd.getTime());
	}

	/**   
	 * 将时间转换为短时间格式字符串 yyyy-MM-dd    
	 * @param strDate   
	 * @return   
	 */
	private static String dateToStr(Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		return formatter.format(date);
	}

	/**   
	 * 格式化日期为短时间格式字符串 yyyy-MM-dd    
	 * @param date   
	 * @return   
	    * @throws ParseException 
	 */
	public static String formateDate(String date) throws ParseException {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		Date d = formatter.parse(date);
		return formatter.format(d);
	}

	/**
	 * 获得某日期与周日相差的天数    
	 * @param date
	 * @return
	 */
	private static int getMondayPlus(Date date) {
		Calendar cd = Calendar.getInstance();
		cd.setTime(date);
		// 获得今天是一周的第几天，星期日是第一天，星期二是第二天......    
		int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; //因为按中国礼拜一作为第一天所以这里减1  
		if (dayOfWeek == 1) {
			return 0;
		} else {
			return 1 - dayOfWeek;
		}
	}

	/**
	 * 获得指定日期对应本周星期日的日期           
	 * @param date
	 * @return
	 */
	public static String getCurrentWeekday(Date date) {
		weeks = 0;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus + 6);
		Date monday = currentDate.getTime();
		String preMonday = dateToStr(monday);
		return preMonday;
	}

	/**
	 *  获得指定日期对应本周星期一的日期     
	 * @param date
	 * @return
	 */
	public static String getMondayOFWeek(Date date) {
		weeks = 0;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus);
		Date monday = currentDate.getTime();
		String preMonday = dateToStr(monday);
		return preMonday;
	}

	/**
	 *  获得指定日期对应上周星期日的日期    
	 * @param date
	 * @return
	 */
	public static String getPreviousWeekSunday(Date date) {
		weeks = 0;
		weeks--;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus + weeks);
		Date monday = currentDate.getTime();
		String preMonday = dateToStr(monday);
		return preMonday;
	}

	/**
	 *  获得指定日期对应上周星期一的日期    
	 * @param date
	 * @return
	 */
	public static String getPreviousWeekday(Date date) {
		weeks = 0;
		weeks--;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus + 7 * weeks);
		Date monday = currentDate.getTime();
		String preMonday = dateToStr(monday);
		return preMonday;
	}

	/**
	 *  获得指定日期对应周星期一的日期       
	 * @param date
	 * @return
	 */
	public static String getNextMonday(Date date) {
		weeks++;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus + 7);
		Date monday = currentDate.getTime();
		String preMonday = dateToStr(monday);
		return preMonday;
	}

	/**
	 * 获得指定日期对应下周星期日的日期    
	 * @param date
	 * @return
	 */
	public static String getNextSunday(Date date) {
		weeks++;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus + 7 + 6);
		Date monday = currentDate.getTime();
		String preMonday = dateToStr(monday);
		return preMonday;
	}

	/**
	 * 获取某日期满足类型的 1.前阶段开始结束日期 2.本阶段开始结束日期。格式：yyyy-MM-dd
	 * @param type 1=按日，2=按周，3=按月，4=按年
	 * @param dateStr 指定的日期字符串 非空
	 * @return 根据type不同返回不同的数组如：参数=[2,2012-07-18] --> 返回[2012-07-09,2012-07-15,2012-07-16,2012-07-22]
	 */
	public static String[] getDateByType(int type, String dateStr) {
		String pattern = "yyyy-MM-dd";
		String lastDateBegin = dateStr;
		String lastDateEnd = dateStr;
		String nowDateBegin = dateStr;
		String nowDateEnd = dateStr;
		try {
			Date date = parse(dateStr);
			switch (type) {
			case 1:
				//1.按日查询
				nowDateBegin = format(date, pattern);
				nowDateEnd = nowDateBegin;
				lastDateBegin = format(beforeNDays(date, 1), pattern);
				lastDateEnd = lastDateBegin;
				break;
			case 2:
				//2.按周查询
				nowDateBegin = getMondayOFWeek(date);
				nowDateEnd = getCurrentWeekday(date);
				lastDateBegin = getPreviousWeekday(date);
				lastDateEnd = getPreviousWeekSunday(date);
				break;
			case 3:
				//2.按月查询
				nowDateBegin = getDateStr(getYear(date), getMonth(date) + 1, 1);
				nowDateEnd = getDateStr(getYear(date), getMonth(date) + 1, getLastDayOfTheMonth(date));
				lastDateBegin = getDateStr(getYear(date), getMonth(date), 1);
				Date lastDate = parse(lastDateBegin);
				lastDateEnd = getDateStr(getYear(date), getMonth(lastDate) + 1, getLastDayOfTheMonth(lastDate));
				break;
			case 4:
				//2.按年查询
				nowDateBegin = getDateStr(getYear(date), 1, 1);
				nowDateEnd = getDateStr(getYear(date), 12, 31);
				lastDateBegin = getDateStr(getYear(date) - 1, 1, 1);
				lastDateEnd = getDateStr(getYear(date) - 1, 12, 31);
				break;
			}
			//System.out.println(type+" (日周月年).   "+lastDateBegin+" 至   "+lastDateEnd+" |  "+nowDateBegin+"  至   "+nowDateEnd);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return new String[] { lastDateBegin, lastDateEnd, nowDateBegin, nowDateEnd };
	}

	/*
	 * 为了适应银行日期格式，截取时间信息
	 */
	public static String getTimeInfo(String time, String op) {
		String info = null;
		if (time == null || "".equals(time) || "".equals(op)) {
			info = "";
		}

		if ("date".equals(op.trim())) {
			time = time.substring(0, 10);
			info = time.replaceAll("-", "");
		} else if ("time".equals(op.trim())) {
			time = time.substring(11, 19);
			info = time.replaceAll(":", "");
		}
		return info;
	}

	/**
	 * 特殊处理- 银行返回的时间，转换为正常的时间日期
	 * @param date
	 * @param op
	 * @return
	 */
	public static String formateBankTime(String date, String op) {
		String time = "";
		if (date != null && (date.length() == 8 || date.length() == 6)) {
			if ("date".equals(op.trim())) {
				time = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
			} else if ("time".equals(op.trim())) {
				time = date.substring(0, 2) + ":" + date.substring(2, 4) + ":" + date.substring(4, 6);
			}
		}
		return time;
	}

	/**
	 * 特殊处理-合并银行返回的字符串为 带年月日 时分秒的时间戳
	 * @param date
	 * @param time
	 * @return
	 */
	public static String mergeDateStamp(String date, String time) {
		return date + " " + time;
	}

	/**
	 * 获取两日期的天数差 yyyy-MM-dd
	 * @param startDay 开始日期
	 * @param endDay 结束日期
	 * @return
	 */
	public static long getBetweenDays(String startDay, String endDay) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Long sdate = null;
		Long edate = null;
		try {
			sdate = df.parse(startDay).getTime();
			edate = df.parse(endDay).getTime();
		} catch (Exception e) {
			System.out.println("时间转换有误！");
		}

		long num = edate - sdate;
		long oneDaylong = 24 * 60 * 60 * 1000;

		return num / oneDaylong;
	}

	/**
	 * 根据开始日期计算结束日期
	 * @param beginDate开始日期
	 * @param month 间隔的月数
	 * @return
	 * @throws ParseException
	 */
	public static String calculateEndDate(String beginDate, int month) throws ParseException {
		//将开始时间赋给日历实例
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		Date d = formatter.parse(beginDate);
		Calendar sCalendar = Calendar.getInstance();
		sCalendar.setTime(d);
		sCalendar.add(Calendar.MONTH, month);
		return dateToStr(sCalendar.getTime());
	}

	/**
	 * 根据一个月中的某日期获取本月的第一天
	 * @param date
	 * @return
	 */
	public static String getMonthFirstDate(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyy");
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 0);
		//设置为1号,当前日期既为本月第一天 
		c.set(Calendar.DAY_OF_MONTH, 1);
		String first = format.format(c.getTime());
		return first;
	}

	/**
	 * 根据一个月中的某日期获取本月的最后一天
	 * @param date
	 * @return
	 */
	public static String getMonthLastDate(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyy");
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
		String last = format.format(c.getTime());
		return last;
	}

	/**
	 * 根据当前日期算出之前或之后几天的日期
	 * description:  getBeforeOrAfterDate(Date date, 5)
	 * result:		2015-07-23 15:11:39:970
					2015-07-28
	 * @param date
	 * @param days
	 * @return  
	 * @author lxsong
	 * @update 2015-7-23
	 */
	public static String getBeforeOrAfterDate(Date currentDate, String days) {
		Calendar cd = Calendar.getInstance();
		cd.setTime(currentDate);
		cd.add(GregorianCalendar.DATE, Integer.parseInt(days));
		return dateToStr(cd.getTime());
	}

	/**
	 *  获得指定日期对应本周星期*的日期     
	 * @param date
	 * @param 星期*
	 * @return
	 */
	public static String getMondayOFWeek(Date date, int i) {
		weeks = 0;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus + (i % 7) - 1);
		Date monday = currentDate.getTime();
		String preMonday = dateToStr(monday);
		return preMonday;
	}

	/**
	 *  获得指定日期对应本周星期*的后14天日期     
	 * @param date
	 * @param i
	 * @return
	 */
	public static String getDoubleMondayOFWeek(Date date, int i) {
		weeks = 0;
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.setTime(date);
		currentDate.add(GregorianCalendar.DATE, mondayPlus + (i % 7) - 1);
		Date monday = currentDate.getTime();

		Calendar cd = Calendar.getInstance();
		cd.setTime(monday);
		cd.add(GregorianCalendar.DATE, 14);
		return dateToStr(cd.getTime());

	}

	/**
	* 获取当前日期是星期几<br>
	* 
	* @param dt 
	* @return 当前日期是星期几  0-7    "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"
	*/
	public static String getWeekOfDate(Date dt) {
		String[] weekDays = { "0", "1", "2", "3", "4", "5", "6" };
		Calendar cal = Calendar.getInstance();
		cal.setTime(dt);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}

	/**
	* 获取
	* @param dt 
	* @param creatDate  创建日期
	* @return 
	*/

	public static boolean getDoubleWeekOfDate(Date dt, Date creatDate) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(dt);
		int dti = calendar.get(Calendar.WEEK_OF_YEAR);

		Calendar calendarc = Calendar.getInstance();
		calendarc.setFirstDayOfWeek(Calendar.MONDAY);
		calendarc.setTime(creatDate);

		int dtc = calendarc.get(Calendar.WEEK_OF_YEAR);

		if ((dti - dtc) % 2 == 0) {
			return true;
		} else {
			return false;
		}

	}

	public static void main(String[] args) throws Exception {
		/*System.out.println("2012-08-29 12:20:10".length());
		System.out.println(DateUtil.getTimeInfo("2012-08-29 12:20:10", "date"));
		System.out.println(DateUtil.getTimeInfo("2012-08-29 12:20:10", "time"));
		System.out.println(DateUtil.getBetweenDays("2012-08-29", "2012-08-30"));*/
		//		System.out.println(DateUtil.calculateEndDate( "2012-02-29",12));

		System.out.println("获得当前日期时间:                 " + getNowTimeWithOutMinutes());//获取当前日期时间，格式yyyy-MM-dd
		System.out.println("获得指定日期对应本周星期*的日期 :      " + getMondayOFWeek(new Date(), 5));//获得指定日期对应本周星期*的日期 
		System.out.println("获得指定日期对应本周星期*的后14天日期:  " + getDoubleMondayOFWeek(new Date(), 3));// 获得指定日期对应本周星期*的后14天日期  
		System.out.println("获得指定日期对应本周星期*的后14天日期:  " + getDoubleMondayOFWeek(strToDate("2015-08-12", "yyyy-MM-dd"), 3));// 获得指定日期对应本周星期*的后14天日期
		System.out.println("获得指定日期对应本周星期*的后14天日期:  " + getDoubleMondayOFWeek(strToDate("2015-08-26", "yyyy-MM-dd"), 3));// 获得指定日期对应本周星期*的后14天日期
		System.out.println("获取当前日期是星期几:  " + getWeekOfDate(strToDate("2015-08-09", "yyyy-MM-dd")));
		System.out.println("11111111111:               "
				+ getDoubleWeekOfDate(strToDate("2015-08-13", "yyyy-MM-dd"), strToDate("2015-07-30", "yyyy-MM-dd")));// 获取当前日期是星期几
	}
}
